package cn.xeblog.server.util;

import cn.hutool.cache.impl.LFUCache;
import cn.hutool.core.lang.RegexPool;
import cn.hutool.core.text.UnicodeUtil;
import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * 百度翻譯
 *
 * @author nn200433
 * @date 2022年03月24日 0024 10:54:30
 */
@Slf4j
public class BaiDuFyUtil {

    /**
     * 排除双字节中文正则
     */
    private final Pattern EXCLUDE_DOUBLE_BYTE_REGEX = Pattern.compile("^[\\x00-\\xff]+$");
    private final Pattern EXCLUDE_DOUBLE_BYTE_CHINESE_REGEX = Pattern.compile("^[\\u4e00-\\u9fa5]+$");
    private final Pattern EXCLUDE_DOUBLE_BYTE_JAPANESE_REGEX = Pattern.compile("^[\\u3040-\\u309F\\u30A0-\\u30FF]+$");
    private final Pattern EXCLUDE_DOUBLE_BYTE_KOREAN_REGEX = Pattern.compile("^[\\uac00-\\ud7ff]+$");

    private static final LFUCache<String, String> cache = new LFUCache<>(1000);
    private static final String APP_SALT = "xechat";
    private static final String url = "https://fanyi-api.baidu.com/api/trans/vip/translate";

    private final String appId;
    private final String appKey;

    public BaiDuFyUtil(String appId, String appKey) {
        this.appId = appId;
        this.appKey = appKey;
    }

    /**
     * 翻译
     *
     * @param query 翻译的文本
     * @return {@link String }
     * @author nn200433
     */
    public String translate(String query) {
        // 无翻译配置返回
        if (StrUtil.isAllBlank(this.appId, this.appKey)) {
            return query;
        }

        // 不符合要求，返回
        //final boolean isIncludeChinese = !ReUtil.isMatch(EXCLUDE_DOUBLE_BYTE_REGEX, query);
        final boolean isUrlHttp = ReUtil.isMatch(RegexPool.URL_HTTP, query);
        final boolean isUrl = ReUtil.isMatch(RegexPool.URL, query);
        final boolean isNumber = ReUtil.isMatch(RegexPool.NUMBERS, query);
        final boolean isTime = ReUtil.isMatch(RegexPool.TIME, query);
        final boolean isEmail = ReUtil.isMatch(RegexPool.EMAIL, query);
        final boolean isAtStart = StrUtil.startWith(query, "@");
        final boolean isMatch = isUrlHttp || isUrl || isNumber || isTime || isEmail || isAtStart;
        //final boolean isMatch = isIncludeChinese || isUrlHttp || isUrl || isNumber || isTime || isEmail || isAtStart;

//        final boolean isUri = ReUtil.isMatch(RegexPool.URI, query);
//        final boolean isIncludeJapanese = ReUtil.isMatch(EXCLUDE_DOUBLE_BYTE_JAPANESE_REGEX, query);
//        final boolean isIncludeKorean = ReUtil.isMatch(EXCLUDE_DOUBLE_BYTE_KOREAN_REGEX, query);

        if (StrUtil.isAllBlank(this.appId, this.appKey) || isMatch) {
            return query;
        }

        // 准备进行翻译
        String result = cache.get(query);
        if (StrUtil.isNotBlank(result)) {
            log.info("======> [百度翻译] 缓存命中 单词 = {} | 结果 = {}", query, result);
            return StrUtil.format("{}（机翻：{}）", query, result);
        }

        Map<String, Object> paramsMap = new HashMap<String, Object>(6);
        paramsMap.put("q", query);
        paramsMap.put("from", "auto");
        paramsMap.put("to", "zh");
        paramsMap.put("appid", this.appId);
        paramsMap.put("salt", APP_SALT);
        paramsMap.put("sign", SecureUtil.md5(this.appId + query + APP_SALT + this.appKey));

        String post = HttpUtil.post(url, paramsMap);
        log.debug("---> [百度翻译] 单词 = {} | 结果 = {}", query, post);
        log.debug("---> [百度翻译] 请求参数 {}", JSONUtil.toJsonStr(paramsMap));
        JSONObject resultObj = JSONUtil.parseObj(post);
        String eCode = resultObj.getStr("error_code");
        if (StrUtil.isNotBlank(eCode)) {
            return StrUtil.EMPTY;
        }
        String dst = UnicodeUtil.toString(resultObj.getJSONArray("trans_result").getJSONObject(0).getStr("dst"));
        log.debug("---> [百度翻译] 最终取值 = {}", dst);
        cache.put(query, dst);

        return StrUtil.format("{}（机翻：{}）", query, dst);
    }

    public static void main(String[] args) {

//        String query = "안녕하세요";
//        String query = "こんにちは";
//        String query = "。。。。";
        String query = "hello";
        System.out.println(UnicodeUtil.toUnicode(query));

        String appId = "20191220000367955";
        String appKey = "GFYIcuwB34EfUtx_9Hd6";
        BaiDuFyUtil baiDuFyUtil = new BaiDuFyUtil(appId, appKey);
        String translate = baiDuFyUtil.translate(query);
        System.out.println(translate);
    }

}
